// 这个就是字典翻译

// 所以 , 要建立映射关系
//  apple:苹果 -- 哈希 -- unordered_map
#pragma once
#include "Common.hpp"
#include "InetAddr.hpp"
#include "Log.hpp"
#include <unordered_map>
#include <fstream>

// 是基于文件的

const std::string defaultdict = "./dictionary.txt"; // 字典默认文件路径
const std::string split = ": ";                     // 分割字符串的标识符

class Dict
{
public:
    Dict(const std::string &path = defaultdict)
        : _file_path(path)
    {
    }
    // 加载字典 -- 就是打开文件往 _dict 中添加映射关系
    bool LoadDict()
    {
        // 打开文件
        std::ifstream in(_file_path);
        if (!in.is_open())
        {
            LOG(LogLevel::FATAL) << "open dict file error !";
            return false;
        }

        // 加载 -- 构建映射
        // 因为是一个字符串 : "apple: 苹果" , 风格就是 xx:+空格xx
        // 所以构建键值对 , 要分割字符串

        // 就是读取文件的每一行进行分割处理
        std::string line;
        while (std::getline(in, line)) // 逐行读取文件
        {
            auto pos = line.find(split);
            if (pos == std::string::npos)
            {
                // 每找到 , 就继续找 , 提示一下解析失败 , 分割失败
                LOG(LogLevel::WARNING) << "解析失败 !";
                continue; // 继续解析
            }

            // 解析成功了 , 该构建映射了 , 中英映射
            // 分割子串 find -- (]  -- 所以 , pos位置就是英文结束
            // find 是返回的匹配的第一个位置
            std::string English = line.substr(0, pos);
            std::string Chinese = line.substr(pos + split.size()); // 这样就跳过分隔符 , 到一个中文处

            // 如果找到但是映射一个为空
            if (English.empty() || Chinese.empty())
            {
                LOG(LogLevel::WARNING) << "无效内容 : " << line;
                continue;
            }

            // 建立映射
            _dict.insert(std::make_pair(English,Chinese));

            LOG(LogLevel::DEBUG) << "加载 : " << line;
        }

        in.close();

        return true;
    }

    // 翻译
    std::string Translate(const std::string &word, InteAddr &addr)
    {
        // 翻译就是查找单词 , 有无映射
        auto iter = _dict.find(word);
        if (iter == _dict.end())
        {
            // 没找到
            LOG(LogLevel::ERROR) << "进入翻译 : [ " << addr.GetIp() << ":"<< addr.GetPort() << " ]  { " << word << "-> " << " }";
            return "None";
        }
        LOG(LogLevel::ERROR) << "进入翻译 : [ " << addr.GetIp() << ":" << addr.GetPort() << " ]  { " << word << "-> " << iter->second << " }";
        return iter->second;
    }

    ~Dict() {}

private:
    std::unordered_map<std::string, std::string> _dict; // 字典映射
    std::string _file_path;                             // 文件路径
};